<script setup lang="ts">
import type { SysFileVo } from '#/system/file/file'
import type { ImageInstance, UploadProps, UploadUserFile } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'

const props = withDefaults(defineProps<{
  /**
   * 最大上传数量
   */
  limit?: number
  /**
   * 公开资源
   */
  public?: boolean
}>(), {
  limit: 2,
  public: true,
})

const modelVal = defineModel<string>()

const fileList = ref<UploadUserFile[]>([])

// 预览
let previewImg = $ref('')
const previewRef = $ref<ImageInstance>()

// 上传地址
const action = $computed(() => {
  if (props.public) {
    return '/api/admin-api/system/file/upload/public'
  }
  return '/api/admin-api/system/file/upload'
})

// 请求头
const headers = $computed(() => {
  if (props.public)
    return {}
  return {
    Authorization: `Bearer ${useUserStore().accessToken}`,
  }
})

const previewImgList = $computed(() => {
  if (!modelVal.value)
    return []
  return modelVal.value?.split(',')
})

const handlePictureCardPreview: UploadProps['onPreview'] = async (uploadFile) => {
  if (!previewRef)
    return
  previewImg = uploadFile.url!
  await nextTick()
  previewRef?.showPreview()
}

// 上传成功
function handleUploadSuccsess(res: ResultData<SysFileVo>) {
  if (!res.success) {
    Message({
      type: 'error',
      message: res.msg,
    })
  }
  if (modelVal.value === '') {
    modelVal.value = res.data.fileUrl
  }
  else {
    const urlList = modelVal.value?.split(',') ?? []
    urlList.push(res.data.fileUrl)
    modelVal.value = urlList.join(',')
  }
}

// 删除图片
const handleRemove: UploadProps['onRemove'] = (uploadFile) => {
  let url: string | undefined
  if (uploadFile.response) {
    const res = uploadFile.response as ResultData<SysFileVo>
    url = res.data.fileUrl
  }
  else {
    url = uploadFile.url
  }

  const urlList = modelVal.value?.split(',')

  modelVal.value = urlList?.filter(item => item !== url).join(',')
}

watch(() => modelVal, () => {
  if (modelVal.value === undefined || modelVal.value === '') {
    fileList.value = []
    return
  }
  if (fileList.value.length > 0)
    return
  const urlList = modelVal.value?.split(',')
  urlList?.forEach((url) => {
    fileList.value.push({
      url,
      name: url,
      status: 'success',
    })
  })
}, {
  immediate: true,
  deep: true,
})
</script>

<template>
  <div>
    <el-upload
      v-model:file-list="fileList"
      :action="action"
      :on-preview="handlePictureCardPreview"
      :on-success="handleUploadSuccsess"
      :limit="limit"
      :headers="headers"
      :on-remove="handleRemove"
      list-type="picture-card"
    >
      <el-icon><Plus /></el-icon>
    </el-upload>
    <el-image
      ref="previewRef"
      style="width: 0;height: 0;position: absolute;"
      :src="previewImg"
      :preview-src-list="(previewImgList as string[])"
      fit="cover"
    />
  </div>
</template>

<style scoped lang="scss">
:deep .sy-upload-list__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.sy-image {
  width: 100%;
  height: 100%;
}
</style>
